package com.blockmeta.bbs.businesslibrary.launch;


import org.yaml.snakeyaml.Yaml;

import java.io.InputStream;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;

public class YamlParser
{	
	protected Yaml m_yaml;
	protected HashMap<Object, Object>	m_yamlContent;
	
	public YamlParser() 
	{
		m_yaml = new Yaml();
	}
	
	public void load(InputStream io)
	{
		m_yamlContent = (HashMap<Object, Object>)m_yaml.load(io);
	}
	
	public void load(Reader io)
	{
		m_yamlContent = (HashMap<Object, Object>)m_yaml.load(io);
	}
	
	public void load(String yaml)
	{
		m_yamlContent = (HashMap<Object, Object>)m_yaml.load(yaml);
	}
	
	/**
	 * 取得某一層Key 所屬的所有Key值
	 * @param arKeys : 某一層Key的階層 
	 *                 如果查詢Root arKeys數量為0
	 * @return 所有的Key值 如果Key已是最後一層 則回傳的數量為0             
	 */
	public Object[] getKeys(ArrayList<Object> arKeys)
	{
		return getKeys(m_yamlContent, arKeys, 0);
	}
	
	/**
	 * 取得某一層Key 所屬的所有Key值
	 * @param strKeys 以逗號[,]區隔的Key階層 Ex: "0,2" 
	 * @return 所有的Key值 如果Key已是最後一層 則回傳的數量為0             
	 */
	public Object[] getKeys(String strKeys)
	{		
		return getKeys(getKeyArray(strKeys));
	}	
	
	/**
	 * 取得第一層Key的Value
	 * @param key 取得第一層Key
	 * @return 可能是String, Integer, HashMap...
	 */
	public Object getValue(Object key)
	{
		return m_yamlContent.get(key);
	}
	
	/**
	 * 取得某一階層Key 對應的值
	 * @param arKeys 某一層Key的階層 
	 * @return 對應的值 如果Key不是最後一層 則回傳Map Object
	 *                如果是最後一層 可以這樣判斷
	 *                if (value instanceof Integer)
	 *                   Integer a = (Integer)value;
	 *                if (value instanceof String)
	 *                   String b = value.toString();
	 *                Object只有Integer, String, HashMap三種形態
	 *                其他形態(Short, Byte..) 再二次型別轉換
	 */
	public Object getValue(ArrayList<Object> arKeys)
	{
		return getValue(m_yamlContent, arKeys, 0);
	}
	
	/**
	 * 取得某一階層Key 對應的值
	 * @param strKeys 以逗號[,]區隔的Key階層 Ex: "0,2,Text" 
	 * @return 對應的值 如果Key不是最後一層 則回傳Map Object
	 *                如果是最後一層 可以這樣判斷
	 *                if (value instanceof Integer)
	 *                   Integer a = (Integer)value;
	 *                if (value instanceof String)
	 *                   String b = value.toString();
	 */
	public Object getValue(String strKeys)
	{		
		return strKeys != null ? getValue(getKeyArray(strKeys)) : null;
	}
	
	protected ArrayList<Object> getKeyArray(String strKeys)
	{
		ArrayList<Object> arKeys = new ArrayList<Object>();
		
		if (strKeys != null)
		{
			String[] keys = strKeys.split(",");
			for (String str : keys)
			{
				if (str.equals(""))
					continue;
				
				try
				{
					Integer intValue = Integer.valueOf(str);
					arKeys.add(intValue);
				}
				catch(NumberFormatException e)
				{
					arKeys.add(str);
				}
			}
		}
		return arKeys;
	}
	
	protected Object[] getKeys(HashMap<Object, Object> mapValue, ArrayList<Object> arKeys, int index)
	{		
		try
		{
			if (index >= arKeys.size())
			{
				Set<Object> bb = mapValue.keySet();
				return mapValue.keySet().toArray();
			}

			Object key = arKeys.get(index);
			if (mapValue.keySet().contains(key))
			{
				HashMap<Object, Object> value = (HashMap<Object, Object>)mapValue.get(key);
				return getKeys(value, arKeys, ++index);
			}
			else
			{
				return null;
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		return null;		
	}
	
	protected Object getValue(HashMap<Object, Object> mapValue, ArrayList<Object> arKeys, int index)
	{
		try
		{
			if (index >= arKeys.size())
			{
				return null;
			}

			Object key = arKeys.get(index);
			
			if (index == arKeys.size() - 1)
			{
				if (mapValue.keySet().contains(key))
					return mapValue.get(key);
			}
			else
			{
				if (mapValue.keySet().contains(key))
					return getValue((HashMap<Object, Object>)mapValue.get(key), arKeys, ++index);
			}

			return null;
		}
		catch(Exception e)
		{
		}
		return null;		
	}	
}
